package cn.com.basic.framework.aliyun.odps;

import cn.com.basic.framework.aliyun.odps.error.OdpsError;
import cn.com.basic.framework.exception.exceptions.SysException;
import cn.hutool.core.lang.Assert;
import com.aliyun.odps.*;
import com.aliyun.odps.account.Account;
import com.aliyun.odps.account.AliyunAccount;
import org.apache.commons.lang3.StringUtils;

import java.util.Iterator;

/**
 * ODPS 管理器
 *
 * @author zhuxj
 */
public class OdpsManager {

    private String accessId;
    private String accessKey;
    private String endpoint;
    private String defaultProject;
    private Account account;

    private Odps odps;

    private OdpsManager() {

    }

    public Account getAccount() {
        if (this.account == null) {
            Assert.notBlank(this.accessId);
            Assert.notBlank(this.accessKey);
            this.account = new AliyunAccount(this.accessId, this.accessKey);
        }
        return this.account;
    }

    public Odps getOdps() {
        if (this.odps == null) {
            Assert.notBlank(this.endpoint);
            this.odps = new Odps(getAccount());
            this.odps.setEndpoint(this.endpoint);
            if (StringUtils.isNotBlank(this.defaultProject))
                this.odps.setDefaultProject(this.defaultProject);
            else {
                Projects projects = getProjects();
                Iterator<Project> it = projects.iterator(null);
                if (it.hasNext()) {
                    this.odps.setDefaultProject(it.next().getName());
                }
            }
        }
        return this.odps;
    }

    public Projects getProjects() {
        return this.getOdps().projects();
    }

    public Project getProject() {
        try {
            return this.getProjects().get();
        } catch (OdpsException e) {
            throw SysException.newException(OdpsError.GET_PROJECT_ERROR, e);
        }
    }

    public Project getProject(String project) {
        try {
            return this.getProjects().get(project);
        } catch (OdpsException e) {
            throw SysException.newException(OdpsError.GET_PROJECT_ERROR, e);
        }
    }

    public Tables getTables() {
        Assert.notNull(this.odps);
        return this.odps.tables();
    }

    public Table getTable(String table) {
        return this.getTables().get(table);
    }

    public Table getTable(String project, String table) {
        return this.getTables().get(project, table);
    }

    public static OdpsManager newInstance() {
        return new OdpsManager();
    }

    public OdpsManager setAccessId(String accessId) {
        this.accessId = accessId;
        return this;
    }

    public OdpsManager setAccessKey(String accessKey) {
        this.accessKey = accessKey;
        return this;
    }

    public OdpsManager setEndpoint(String endpoint) {
        this.endpoint = endpoint;
        return this;
    }

    public OdpsManager setDefaultProject(String defaultProject) {
        this.defaultProject = defaultProject;
        return this;
    }
}
